<?php

/**
 * This file is part of the Framework03 PHP framework.
 * @author Walter Tamboer
 * @package Framework03
 */

/**
 * The base class for all views.
 */
abstract class FW_View_Abstract
{
    /**
     * @var array The array with variable data.
     */
    private $data = array();
    
    /**
     * @var array The array with view helper prefixes.
     */
    private static $prefixes = array('FW_View_Helper_');
    
    /**
     * @var array The array with view helpers.
     */
    private static $helpers = array();

    /**
     * Adds a helper prefix so that helpers can be found.
     * @param string $prefix The prefix of the helper.
     */
    public static function addHelperPrefix($prefix)
    {
        if (in_array($prefix, self::$prefixes))
            throw new FW_View_Helper_Exception('The view helper prefix "' . $name . '" has already been registered.');

        self::$prefixes[] = $prefix;
    }

    /**
     * Gets a helper with the given name.
     * @param string $name The name of the helper to get.
     * @return FW_View_Helper_Abstract
     */
    public static function getHelper($name)
    {
        $class = null;

        foreach (self::$prefixes as $prefix)
        {
            $className = $prefix . ucfirst($name);

            if (isset(self::$helpers[$className]))
            {
                $class = self::$helpers[$className];
                break;
            }
        }

        if ($class == null)
        {
            foreach (self::$prefixes as $prefix)
            {
                $className = $prefix . ucfirst($name);

                if (FW_Loader::classExists($className))
                {
                    $class = new $className;
                    self::$helpers[$className] = $class;
                    break;
                }
            }
        }

        if ($class == null)
            throw new FW_View_Helper_Exception('The view helper "' . $name . '" could not be found.');

        return $class;
    }

    /**
     * Gets the controller to which this view belongs.
     * @return FW_Controller_Action
     */
    public function getController()
    {
        return $this->controller;
    }

    /**
     * Gets a variable that has been set in this view.
     * @param string $name The name of the variable.
     * @return mixed Returns the value of the requested variable.
     */
    public function get($name)
    {
        return $this->data[$name];
    }

    /**
     * Sets a variable that with the given value.
     * @param string $name The name of the variable.
     * @param mixed $value The value of the variable.
     * @return FW_View_Abstract
     */
    public function set($name, $value)
    {
        $this->data[$name] = $value;
        return $this;
    }
    
    /**
     * Gets all the data variables as an array.
     * @return array Returns an array with all the variables.
     */
    public function getData()
    {
        return $this->data;
    }

    /**
     * Renders the view to the screen.
     * @param FW_Controller_Action $controller The controller that wants the rendering to be done.
     * @param string $actionName The name of the action that wants the rendering to be done.
     */
    abstract public function render(FW_Controller_Action $controller, $actionName);
}
